namespace study45 {
  /**
   * is关键字
   */

  // 1. 使用 is 关键字的类型保护函数
  // 1.1 简单的类型检查
  interface Cat {
    meow(): void;
  }

  interface Dog {
    bark(): void;
  }

  function isCat(animal: Cat | Dog): animal is Cat {
    return (animal as Cat).meow !== undefined
  }

  function makeSound(animal: Cat | Dog) {
    if (isCat(animal)) {
      animal.meow();
    } else {
      animal.bark();
    }
  }

  // 1.2 处理联合类型
  type Fish = { swim: () => void };
  type Bird = { fly: () => void };

  function isFish(pet: Fish | Bird): pet is Fish {
    return (pet as Fish).swim !== undefined;
  }

  function move(pet: Fish | Bird) {
    if (isFish(pet)) {
      pet.swim(); // pet 被推断为 Fish
    } else {
      pet.fly(); // pet 被推断为 Bird
    }
  }

  // 2. 复杂类型保护
  // 2.1 检查多个属性
  interface Square {
    kind: "square";
    size: number;
  }

  interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
  }

  type Shape = Square | Rectangle;

  function isRectangle(shape: Shape): shape is Rectangle {
    return shape.kind === "rectangle";
  }

  function getArea(shape: Shape): number {
    if (isRectangle(shape)) {
      return shape.width * shape.height; // shape 被推断为 Rectangle
    } else {
      return shape.size * shape.size; // shape 被推断为 Square
    }
  }

  // 3. 使用自定义类型保护
  interface Fish1 {
    swim(): void;
  }

  interface Bird1 {
    fly(): void;
  }

  function isFish1(pet: Fish1 | Bird1): pet is Fish1 {
    return (pet as Fish1).swim !== undefined;
  }

  function checkPet(pet: Fish1 | Bird1): void {
    if (isFish(pet)) {
      pet.swim();
    } else {
      pet.fly();
    }
  }

  // 4. 使用 in 操作符
  interface Car {
    drive(): void;
  }

  interface Boat {
    sail(): void;
  }

  function move1(vehicle: Car | Boat): void {
    if ("drive" in vehicle) {
      vehicle.drive();
    } else {
      vehicle.sail();
    }
  }

  // 5. 使用 === 进行特定值判断
  type Direction = "up" | "down" | "left" | "right";

  function moveDirection(direction: Direction): void {
    if (direction === "up") {
      console.log("Moving up!");
    } else if (direction === "down") {
      console.log("Moving down!");
    }
    // Add other cases as needed
  }

  // 6. 使用 switch 语句
  enum Color {
    Red,
    Green,
    Blue
  }

  function chooseColor(color: Color): void {
    switch (color) {
      case Color.Red:
        console.log("Red color chosen.");
        break;
      case Color.Green:
        console.log("Green color chosen.");
        break;
      case Color.Blue:
        console.log("Blue color chosen.");
        break;
      default:
        console.log("Unknown color.");
    }
  }
}